# -*- coding: utf-8 -*-
"""
Created on Tue Sep 24 16:38:53 2024

@author: masanobu-new
"""

import cv2
import numpy as np
import py360convert
from PIL import Image
import pathlib
import hozenLib
import os
import sys

def color_range(img, lower_values, upper_values):
    ''' 
    H, S, Vの範囲でimgを抽出する。
    
    Parameters:
        img: 入力画像
        lower_values: [H, S, V]の下限値リスト
        upper_values: [H, S, V]の上限値リスト

    Returns:
        img_color: 抽出したHSV画像
        img_mask: 抽出したHSV画像のマスク（2値化画像）
    '''
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    lower = np.array(lower_values)
    upper = np.array(upper_values) 
    img_mask = cv2.inRange(hsv, lower, upper)
    img_color = cv2.bitwise_and(img, img, mask=img_mask)
    return img_color, img_mask

def imread(filename, flags=cv2.IMREAD_COLOR):
    ''' 画像を読み込む関数 '''
    try:
        n = np.fromfile(filename, dtype=np.uint8)
        img = cv2.imdecode(n, flags)
        return img
    except Exception as e:
        print(f"Error reading {filename}: {e}")
        return None
    
def imwrite(filename, img, params=None):
    ''' 画像を保存する関数 '''
    try:
        ext = os.path.splitext(filename)[1]
        result, n = cv2.imencode(ext, img, params)

        if result:
            with open(filename, mode='wb') as f:
                n.tofile(f)
            return True
        else:
            print(f"Error writing {filename}")
            return False
    except Exception as e:
        print(f"Error writing {filename}: {e}")
        return False

def process_images(base_folder, incl, veg_low, veg_high, soil_low, soil_high, keep_image):
    ''' 画像を処理して結果をCSVに書き出す '''
    tmp_path = os.path.join(base_folder, 'tmpfiles')
    pathlib.Path(tmp_path).mkdir(parents=True, exist_ok=True)

    with open(os.path.join(base_folder, 'results.csv'), 'w', encoding='shift-jis') as outfile:
        outfile.write(', H, S, V\n')
        outfile.write('植生 low,' + ','.join(map(str, veg_low)) + '\n')
        outfile.write('植生 high,' + ','.join(map(str, veg_high)) + '\n')
        outfile.write('土壌 low,' + ','.join(map(str, soil_low)) + '\n')
        outfile.write('土壌 high,' + ','.join(map(str, soil_high)) + '\n\n')
        outfile.write('ファイルパス,植生,土壌,その他,緯度,経度,撮影日時\n')

        # Hの範囲を0-179に調整
        veg_low[0] //= 2
        veg_high[0] //= 2
        soil_low[0] //= 2
        soil_high[0] //= 2

        # 画像ファイルでループ
        image_files = pathlib.Path(base_folder).glob('*.jpg')
        for image_file in image_files:
            process_single_image(image_file, incl, veg_low, veg_high, soil_low, soil_high, keep_image, outfile)

def process_single_image(image_file, incl, veg_low, veg_high, soil_low, soil_high, keep_image, outfile):
    ''' 単一の画像を処理する '''
    lat_dd, lon_dd, date_time_original = hozenLib.Exifinfo(image_file)

    pix_count = [0, 0, 0]  # [veg, soil, allPix]
    img = np.array(Image.open(image_file))

    if img.ndim == 2:
        img = img[..., None]

    # 足元の4方向を処理
    for n in range(1, 5):
        img_perspective = py360convert.e2p(img, fov_deg=(60, 60), u_deg=(n - 1) * 90, v_deg=incl, out_hw=(500, 500))

        # 2値化画像を作成
        _, veg_image = color_range(img_perspective, veg_low, veg_high)
        _, soil_image = color_range(img_perspective, soil_low, soil_high)

        if keep_image == 'KEEP':
           
            save_processed_images(tmp_path, image_file, img_perspective, veg_image, soil_image, n)

        # 2値化画像の画素数をカウント
        pix_count[0] += cv2.countNonZero(veg_image)  # 植生のマスク部分の画素数
        pix_count[1] += cv2.countNonZero(soil_image)  # 土壌のマスク部分の画素数
        pix_count[2] += img_perspective.size  # 全画素数

    # 結果をCSVに書き出す
    write_results_to_csv(image_file, pix_count, lat_dd, lon_dd, date_time_original, outfile)

def save_processed_images(tmp_path, image_file, img_perspective, veg_image, soil_image, direction):
    ''' 処理した画像を保存 '''
    base_name = os.path.splitext(os.path.basename(image_file))[0]
    out_fn = os.path.join(tmp_path, os.path.basename(image_file))
    img_fn = os.path.join(tmp_path, f"{base_name}_{direction}.jpg")

    imwrite(out_fn, img_perspective)
    imwrite(os.path.splitext(img_fn)[0] + '_veg.jpg', veg_image)
    imwrite(os.path.splitext(img_fn)[0] + '_soil.jpg', soil_image)

import csv

def write_results_to_csv(image_file, pix_count, lat_dd, lon_dd, date_time_original, outfile):
    ''' Write results to a CSV file '''
    
    veg_pixels, soil_pixels, image_size = pix_count

    # Calculate percentages
    if image_size > 0:
        veg_percentage = (veg_pixels / image_size * 100)
        soil_percentage = (soil_pixels / image_size * 100)
        non_veg_soil_percentage = 100 - (veg_percentage + soil_percentage)
    else:
        veg_percentage = soil_percentage = non_veg_soil_percentage = 0.0

    # Prepare data for CSV
    row = [
        image_file,
        round(veg_percentage, 1),
        round(soil_percentage, 1),
        round(non_veg_soil_percentage, 1),
        lat_dd,
        lon_dd,
        date_time_original
    ]

    # Write to CSV using csv.writer
    writer = csv.writer(outfile)
    writer.writerow(row)


# 実行部分

if __name__ == "__main__":
    args = sys.argv
    #args = ['evalVRimage.py', 'C:/Users/user/Desktop/Temp', -55, 70, 0, 0, 150, 255, 255, 0, 0, 0, 80, 255, 255, 'KEEP']
    base_folder_path = args[1]
    tmp_path = os.path.join(base_folder_path,"tmpfiles")
    incl = int(args[2])
    veg_low = [int(n) for n in args[3:6]]
    veg_high = [int(n) for n in args[6:9]]
    soil_low = [int(n) for n in args[9:12]]
    soil_high = [int(n) for n in args[12:15]]
    keep_image = args[15]

    process_images(base_folder_path, incl, veg_low, veg_high, soil_low, soil_high, keep_image)
